/*******************************************************************
* Copyright (c) 2010 BSUIR <romkisel@gmail.com>

* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:

* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
********************************************************************/

#include "dlight.h"
#include "optixscene.h"
#include <QDebug>
#include <QPainter>
#include <QPolygonF>
#include <QGraphicsSceneContextMenuEvent>

DLight::DLight(ShadowMap *shadMap, qreal d, qreal length, int numLines, int lineSize, QColor color):
        OptixItem(color)
{
    this->shadMap = shadMap;
    this->mD = d;
    this->mLength = length;
    this->mNumLines = numLines;
    this->mLineSize = lineSize;

    this->setFlag(QGraphicsItem::ItemIsMovable, true);
    this->setFlag(QGraphicsItem::ItemIsSelectable, true);
}

void DLight::drawLightLine(QLineF line)
{
    line.setP1(line.p1() + QPointF(shadMap->getMap()->width()/2,
                                    shadMap->getMap()->height()/2));
    line.setP2(line.p2() + QPointF(shadMap->getMap()->width()/2,
                                    shadMap->getMap()->height()/2));

    QPen pen(Qt::black, mLineSize, Qt::SolidLine);
    QPainter p;
    p.begin(shadMap->getMap());
    //p.setRenderHint(QPainter::Antialiasing, false);
    p.setCompositionMode(QPainter::CompositionMode_Clear);
    p.setPen(pen);
    p.drawLine(line);
    p.setCompositionMode(QPainter::CompositionMode_SourceOver);
    QColor col(color.red(), color.green(), color.blue(), 100);
    p.setPen(QPen(col, mLineSize, Qt::SolidLine));
    p.drawLine(line);
    p.end();
}

void DLight::drawPolygonLight(QPolygonF poly)
{
    QPolygonF drawPoly;
    for (int i = 0; i < poly.size(); ++i)
        drawPoly << poly[i] + QPointF(shadMap->getMap()->width()/2,
                                      shadMap->getMap()->height()/2);
    QPainter p;
    p.begin(shadMap->getMap());
    //substract the light from shadow map
    p.setCompositionMode(QPainter::CompositionMode_Clear);
    p.setPen(Qt::NoPen);
    p.setBrush(Qt::black);
    p.drawPolygon(drawPoly);
    p.setCompositionMode(QPainter::CompositionMode_SourceOver);
    p.setPen(Qt::NoPen);
    p.setBrush(QColor(color.red(), color.green(), color.blue(), 100));
    p.drawPolygon(drawPoly);
    p.end();
}

qreal DLight::getD()
{
    return this->mD;
}

qreal DLight::getLength()
{
    return this->mLength;
}

int DLight::getNumLines()
{
    return this->mNumLines;
}

int DLight::getLineSize()
{
    return this->mLineSize;
}

void DLight::setD(qreal d)
{
    this->mD = d;
}

void DLight::setLength(qreal length)
{
    this->mLength = length;
}

void DLight::setNumLines(qreal nlines)
{
    this->mNumLines = nlines;
}

void DLight::setLineSize(qreal lsize)
{
    this->mLineSize = lsize;
}

QRectF DLight::boundingRect() const
{
    return QRectF(-50, -mD/2, 50, mD);
}

void DLight::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    if (isSelected())
    {
        painter->setPen(QPen(Qt::black, 1, Qt::DashLine));
        painter->setBrush(Qt::NoBrush);
        painter->drawRect(this->boundingRect());
    }
    painter->setPen(Qt::green);
    painter->setBrush(Qt::NoBrush);

    painter->drawLine(QPointF(0, -mD/2), QPointF(0, mD/2));
    painter->drawLine(QPointF(0, -mD/2), QPointF(-50, -mD/2+mD/5));
    painter->drawLine(QPointF(0, mD/2), QPointF(-50, mD/2-mD/5));
    painter->drawLine(QPointF(-50, -mD/2+mD/5), QPointF(-50, mD/2-mD/5));
}

void DLight::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    scene()->clearSelection();
    setSelected(true);

    OptixScene *sc = dynamic_cast<OptixScene *>(scene());
    if (sc)
    {
        sc->ContextMenu()->exec(event->screenPos());
    }
}
